Skip to content

Conversation

@amontoison
Copy link
Contributor

@amontoison amontoison commented Nov 2, 2025

@odow
When I created the C / Julia interface for Uno, I checked a few times the interfaces of other nonlinear solvers (Ipopt, KNITRO, GALAHAD) and I noticed that in Ipopt.jl we never provide a way to pass user_data.
This means that model::Optimizer is passed as a closure, and the same applies to model::AbstractNLPModel in NLPModelsIpopt.jl.

In UnoSolver.jl, I added an option to pass user_data / user_model when creating the internal solver model (Ipopt.IpoptProblem in this repository).
If user_data is nothing, we keep the current signature; otherwise, we pass user_data / user_model as the first argument to all Julia callbacks.
This is what we expect in the signatures of the NLP API in MathOptInterface.jl or NLPModels.jl.

I also think it is a clean way to pass a list of parameters to an objective or constraints.
For example, if we have a complex physical problem, we would like to store them in a Julia structure and pass this structure as an argument to the Julia functions.
I find it neater than using closures.

The current PR is non-breaking because, by default, user_data / user_model is nothing.
I would like to have your point of view (as well as that of other users) before I add unit tests for coverage.

Ipopt.jl: https://github.com/jump-dev/Ipopt.jl/blob/master/ext/IpoptMathOptInterfaceExt/MOI_wrapper.jl#L1242-L1264
UnoSolver.jl: https://github.com/cvanaret/Uno/blob/main/interfaces/Julia/ext/UnoSolverMathOptInterfaceExt/MOI_wrapper.jl#L1294-L1301

@codecov
Copy link

codecov bot commented Nov 2, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.48%. Comparing base (3a7aed2) to head (bd966d0).

Files with missing lines Patch % Lines
src/C_wrapper.jl 75.00% 6 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##            master     #514      +/-   ##
===========================================
- Coverage   100.00%   99.48%   -0.52%     
===========================================
  Files            5        5              
  Lines         1154     1170      +16     
===========================================
+ Hits          1154     1164      +10     
- Misses           0        6       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@odow
Copy link
Member

odow commented Nov 2, 2025

I'm not really in favour of this. What's the problem with a closure?

@odow
Copy link
Member

odow commented Nov 2, 2025

Do you have a worked example of code that would be improved with this?

@odow
Copy link
Member

odow commented Nov 2, 2025

Can't this just be achieved with:

    prob = Ipopt.CreateIpoptProblem(
        n,
        x_L,
        x_U,
        m,
        g_L,
        g_U,
        nnzJ,
        nnzH,
        x -> eval_f(user_data, x),
        (args...) -> eval_g(user_data, args...),
        (args...) -> eval_grad_f(user_data, args...),
        (args...) -> eval_jac_g(user_data, args...),
        (args...) -> eval_h(user_data, args...),
    )

I don't really want to make changes to the C API, and adding multiple ways of doing something has a long-term maintenance cost.

@odow odow marked this pull request as draft November 2, 2025 21:42
@odow
Copy link
Member

odow commented Nov 5, 2025

You can convince me of the need for this at JuMP-dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants